﻿using System;
using System.IO;
using System.Threading;
using System.Windows.Forms;

namespace QuickEmailer
{
    public partial class frmSendingDialog : Form
    {
        #region Delegates

        public delegate void UpdateCountLabelCallback(string count);
        public delegate void UpdateProcessedListTextBoxCallback(string text);
        public delegate void UpdateStatusLabelCallback(string text);
        public delegate void UpdateCancelButtonCallback(string text);

        #endregion

        private Thread _thread;
        public UpdateCountLabelCallback UpdateCountLabelDelegate;
        public UpdateProcessedListTextBoxCallback UpdateProcessedListDelegate;
        public UpdateStatusLabelCallback UpdateStatusLabelDelegate;
        public UpdateCancelButtonCallback UpdateCancelButtonDelegate;

        public frmSendingDialog()
        {
            InitializeComponent();
        }

        public string InputFile { get; set; }
        public string SmtpHost { get; set; }
        public int SmtpPort { get; set; }
        public string SmtpUser { get; set; }
        public string SmtpPass { get; set; }
        public bool SmtpAnonymous { get; set; }
        public string EmailMessage { get; set; }
        public bool EmailHtml { get; set; }
        public string FromName { get; set; }
        public string FromEmail { get; set; }
        public string Subject { get; set; }
        
        private void btnCancel_Click(object sender, EventArgs e)
        {
            
            if (_thread.IsAlive)
            {
                string cancelMessage = "Cancelling will only stop processing and will *not* " +
                                       " recall any messages that have already benn sent. " +
                                       "\n\r\n\r Are you sure you want to cancel processing?";

                DialogResult cancelSending = MessageBox.Show(cancelMessage, "Cancel Processing?", MessageBoxButtons.YesNo,
                                                             MessageBoxIcon.Question);
                if (cancelSending == DialogResult.Yes)
                {
                    _thread.Abort();
                    UpdateStatusLabel("Aborted!");
                    UpdateCancelButtonText("Close");
                }
            }

            else
            {
                Close();
            }
            
        }

        private void frmSendingDialog_Load(object sender, EventArgs e)
        {
            ControlBox = false;

            _thread = new Thread(SendMail);
            _thread.Start();
        }

        private void UpdateStatusLabel(string text)
        {
            if (lblStatus.InvokeRequired)
            {
                UpdateStatusLabelDelegate = new UpdateStatusLabelCallback(UpdateStatusLabel);
                Invoke(UpdateStatusLabelDelegate, text);
            }
            else
            {
                lblStatus.Text = text;
            }
        }

        private void UpdateProcessedListTextBox(string text)
        {
            if (richTextBox1.InvokeRequired)
            {
                UpdateProcessedListDelegate = new UpdateProcessedListTextBoxCallback(UpdateProcessedListTextBox);
                Invoke(UpdateProcessedListDelegate, text);
            }
            else
            {
                richTextBox1.Text += "Processed: " + text + "\n";
            }
        }

        private void UpdateCountLabel(string count)
        {
            if (lblProcessCount.InvokeRequired)
            {
                UpdateCountLabelDelegate = new UpdateCountLabelCallback(UpdateCountLabel);
                Invoke(UpdateCountLabelDelegate, count);
            }
            else
            {
                lblProcessCount.Text = "Processed: " + count;
            }
        }

        private void UpdateCancelButtonText(string text)
        {
            if (InvokeRequired)
            {
                UpdateCancelButtonDelegate = new UpdateCancelButtonCallback(UpdateCancelButtonText);
                Invoke(UpdateCancelButtonDelegate, text);

            }
            else
            {
                btnCancel.Text = text;
            }
        }

        private void SendMail()
        {
            int processed = 0;
            UpdateStatusLabel("Processing..");

            try
            {
                var reader = new StreamReader(InputFile);

                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    string[] inputFileParts = line.Split(',');
                    string email = inputFileParts[0];
                    string name = inputFileParts[1];

                    string emailMessageName = EmailMessage.Replace("[name]", name);

                    EmailNotify emailNotify = new EmailNotify
                                                  {
                                                      FromName = FromName,
                                                      FromAddress = FromEmail,
                                                      IsHtml = EmailHtml,
                                                      MessageBody = emailMessageName,
                                                      MessageSubject = Subject,
                                                      SmtpHost = SmtpHost,
                                                      SmtpUser = SmtpUser,
                                                      SmtpPass = SmtpPass,
                                                      ToAddress = email
                                                  };

                    try
                    {
                        emailNotify.SendMessage();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("An exception has occurred: " + ex.Message);
                    }

                    processed += 1;

                    UpdateProcessedListTextBox(email + " (" + name + ")");
                    UpdateCountLabel(processed.ToString());
                    UpdateStatusLabel("Processing");
                }
            }
            catch (FileNotFoundException)
            {
                MessageBox.Show("The specified file cannot be found!");
            }
            catch (DirectoryNotFoundException)
            {
                MessageBox.Show("The specified path cannot be found.");
            }
            catch (IOException)
            {
                MessageBox.Show("An IO Exception has occurred. Perhaps the file is invalid or corrupt?");
            }
            catch (Exception e)
            {
                MessageBox.Show("The follow exception has occurred: " + e.Message);
            }

            UpdateStatusLabel("Done");
            UpdateCancelButtonText("Close");
        }
    }
}